// $Id$
// Licensed under Apache License Version 2.0
// See: http://www.apache.org/licenses/LICENSE-2.0.html
package de.servicezombie.tcmdb.rest.service;

import java.io.InputStream;

import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;

import de.servicezombie.pub.r1.CommonRestResponse;
import de.servicezombie.tcmdb.TcmdbRecordNotFoundException;
import de.servicezombie.tcmdb.TcmdbValidationFailedException;
import de.servicezombie.tcmdb.rest.vo.WsListResult;
import de.servicezombie.tcmdb.rest.vo.WsTestExecution;
import de.servicezombie.tcmdb.rest.vo.WsTestcaseDefinition;

/**
 * <b>Examples</b>
 * 
 * <pre>
 *  GET    /test-executions/active/by-group/M1%20FirstTry.xml
 * </pre>
 * 
 * @author ChKa
 * @see WsTestExecution
 */
@Path("/test-executions")
@Consumes({ "test/json", "application/json", "test/xml", "application/xml" })
@Produces({ "test/json", "application/json", "test/xml", "application/xml" })
public interface TestExecutionService {

	/**
	 * replaces the status of an existing document
	 * use get to have more compatibility with external tools
	 * 
	 * @param testcaseExecutionId
	 *            id of record to update
	 * @param newStatus
	 *            new value for status. Must be configured in Configuration
	 * @param remark
	 *            an optional remark to be saved at this execution document
	 * 
	 * @response {@link CommonRestResponse} with an OK code in case of success
	 * 
	 * @throws TcmdbRecordNotFoundException
	 *             if no record can be found
	 * @throws TcmdbValidationFailedException
	 *             if an invalid status is tried top be set
	 */
	@PUT
	@GET
	@Path("/active/by-id/{testcaseExecutionId}/resolution/{status}")
	void updateStatus(
			@PathParam("testcaseExecutionId") String testcaseExecutionId,
			@PathParam("status") String newStatus,
			@QueryParam("remark") String remark)
			throws TcmdbRecordNotFoundException, TcmdbValidationFailedException;

	/**
	 * update an existing execution document.
	 * 
	 * @param testcaseExecutionId id of exsting document
	 * @param bodyData data as xml stream
	 * 
	 * @response {@link WsTestExecution} in {@link CommonRestResponse} the way 
	 * it is saved in database.
	 * 
	 * @throws TcmdbRecordNotFoundException
	 *             if testcase execution is not available.
	 * @throws TcmdbValidationFailedException
	 *             if body contains data, that may not be set.
	 */
	@PUT
	@Path("/all/by-id/{testcaseExecutionId}")
	void saveExistingExecution(
			@PathParam("testcaseExecutionId") String testcaseExecutionId,
			InputStream bodyData) throws TcmdbRecordNotFoundException, TcmdbValidationFailedException;
	
	/**
	 * 
	 * save a single new execution document based on a template and an
	 * existing testcasedefinition document
	 * 
	 * @param testcaseDefinitionId
	 *            id of an existing testcase definition
	 * 
	 * @param bodyData
	 *            optional body. may be null. if not null must be marshallable as
	 *            a {@link WsTestExecution} document
	 * 
	 * @response {@link WsTestExecution} in {@link CommonRestResponse}
	 * 
	 * @throws TcmdbRecordNotFoundException
	 *             if testcase definition is not available.
	 * @throws TcmdbValidationFailedException
	 *             if body contains data, that may not be set.
	 */
	@POST
	@Path("/all/by-single-testcase-definition/{testcaseDefinitionId}/new")
	void saveNewByTestcaseDefinition(
			@PathParam("testcaseDefinitionId") String testcaseDefinitionId,
			InputStream bodyData)
			throws TcmdbRecordNotFoundException, TcmdbValidationFailedException;

	/**
	 * 
	 * creates new testcase executions based on an existing execution document. Copies 
	 * these values to the new document.
	 * 
	 * <ul>
	 * <li>group</li>
	 * <li>affectedVersion</li>
	 * <li>responsible</li>
	 * <li>resolution is the default resolution</li>
	 * </ul>
	 * 
	 * @param testcaseExecutionId
	 *            id of an existing testcaseExecutionDocument
	 * @param bodyData
	 *            a comma separated list of strings, each one representing an id to an existing
	 *            {@link WsTestcaseDefinition} document
	 * @throws TcmdbRecordNotFoundException
	 *             if either the required execution document is not
	 *             found or at least one of the supplied testcase definitions is missing.
	 */
	@POST
	@Path("/all/by-test-execution/{testcaseExecutionId}/rollout")
	void rolloutMultipleExecutionsByExisting(
			@PathParam("testcaseExecutionId") String testcaseExecutionId,
			InputStream bodyData)
			throws TcmdbRecordNotFoundException;
	/**
	 * @response {@link WsListResult} of strings in {@link CommonRestResponse} each 
	 * string is a group of a testcase execution document.
	 */
	@GET
	@Path("/active/groups")
	void getAllActiveGroups();
	
	/**
	 * @response {@link WsListResult} of {@link WsTestExecution} in {@link CommonRestResponse}. 
	 * Return empty list if group does not exist
	 */
	@GET
	@Path("/active/by-group/{group}")
	void getExecutionDocumentsByGroup(@PathParam("group") String group);	
}
